package com.ruoyi.classai.api;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.jwt.JWT;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.classai.domain.EwcSchool;
import com.ruoyi.classai.domain.EwcTeacher;
import com.ruoyi.classai.domain.dto.TeacherLoginDto;
import com.ruoyi.classai.domain.dto.px.PassWordDto;
import com.ruoyi.classai.domain.dto.px.PxTrainingTeacherInfoDto;
import com.ruoyi.classai.domain.vo.px.PxTrainingTeacherInfoVo;
import com.ruoyi.classai.service.IEwcSchoolService;
import com.ruoyi.classai.service.IEwcTeacherService;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.context.ThirdSessionHolder;
import com.ruoyi.common.core.domain.ThirdSession;
import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.redis.service.RedisService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 用户登录接口
 * @author lcj
 * @date 2025年02月27日 11:56
 */
@Slf4j
@Validated
@RestController
@Tag(name = "用户登录接口", description = "教师登录")
@RequestMapping("/api")
public class LoginApi {

    @Autowired
    private IEwcTeacherService teacherService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private IEwcSchoolService schoolService;

    /**
     * 教师登录
     * @param loginDto 登录信息
     * @return 登录结果
     */
    @Operation(summary = "教师登录接口")
    @PostMapping("/login/teacher")
    public AjaxResult teacherLogin(@Valid @RequestBody TeacherLoginDto loginDto){
        //验证验证码
        checkCaptcha(loginDto.getCode(), loginDto.getUuid());
        //解密密码
        AES aes = new AES("CBC", "PKCS7Padding", Constants.AES_KEY.getBytes(), Constants.AES_IV.getBytes());
        String password=aes.decryptStr(loginDto.getPassword(), CharsetUtil.CHARSET_UTF_8);
        //验证登录信息
        EwcTeacher teacher=teacherService.getOne(Wrappers.<EwcTeacher>lambdaQuery().eq(EwcTeacher::getTeacherNo,loginDto.getAccount())
                .eq(EwcTeacher::getStatus, Constants.COMMON_SUCCESS));
        if (Objects.isNull(teacher)){
            return AjaxResult.error("账户或密码错误");
        }
        if (!Objects.equals(teacher.getPassword(),DigestUtil.md5Hex(password))){
            return AjaxResult.error("账户或密码错误");
        };
        //判断学校是否正常
        EwcSchool school=schoolService.getOne(Wrappers.<EwcSchool>lambdaQuery().eq(EwcSchool::getId,teacher.getSchoolId())
                .eq(EwcSchool::getStatus,Constants.COMMON_SUCCESS));
        if (Objects.isNull(school)){
            return AjaxResult.error("学校暂未开通");
        }
        //生成token
        String token= JWT.create()
                .setPayload("timestamp",System.currentTimeMillis())//过期时间
                .setPayload("uid", teacher.getId())//用户id
                .setKey(Constants.AES_KEY.getBytes())//授权密钥
                .sign();
        ThirdSession thirdSession=new ThirdSession();
        thirdSession.setAccount(teacher.getTeacherNo());
        thirdSession.setId(teacher.getId());
        thirdSession.setTeacherName(teacher.getTeacherName());
        thirdSession.setSchoolId(teacher.getSchoolId());
        thirdSession.setTitle(teacher.getTitle());
        thirdSession.setPhotoPath(teacher.getPhotoPath());
        thirdSession.setMobile(teacher.getTeacherPhone());
        thirdSession.setTeacherEmail(teacher.getTeacherEmail());
        redisService.setCacheObject(CacheConstants.API_TOKEN_CACHE+token, JSONObject.toJSONString(thirdSession),30L, TimeUnit.DAYS);
        log.info("用户登录成功");
        JSONObject resultJson=new JSONObject();
        resultJson.put("token",token);
        resultJson.put("userInfo",thirdSession);
        return AjaxResult.success("登录成功",resultJson);
    }

    /**
     * 登录退出
     * @return 登录结果
     */
    @Operation(summary = "登录退出")
    @RequestMapping("/logout")
    public AjaxResult teacherLogin(@RequestHeader("third-session") String token){
        redisService.deleteObject(CacheConstants.API_TOKEN_CACHE+token);
        return AjaxResult.success("退出成功");
    }

    /**
     * 查询老师资料
     * @return 结果
     */
    @Operation(summary = "查询老师资料")
    @PostMapping("/getTeacherById")
    public AjaxResult getTeacherById(){
        EwcTeacher teacher=teacherService.getById(ThirdSessionHolder.getThirdSession().getId());
        if (Objects.isNull(teacher)){
            return AjaxResult.error("没有查询到用户信息");
        }
        PxTrainingTeacherInfoVo teacherInfoVo=new PxTrainingTeacherInfoVo();
        BeanUtils.copyProperties(teacher,teacherInfoVo);
        return AjaxResult.success("查询成功",teacherInfoVo);
    }

    /**
     * 修改老师资料
     * @return 结果
     */
    @Operation(summary = "修改老师资料")
    @PostMapping("/updateTeacher")
    public AjaxResult updateTeacher(@Valid @RequestBody PxTrainingTeacherInfoDto trainingTeacherInfoDto){
        trainingTeacherInfoDto.setId(ThirdSessionHolder.getThirdSession().getId());
        teacherService.updateTeacherByWxmini(trainingTeacherInfoDto);
        return AjaxResult.success("更新成功");
    }

    /**
     * 修改密码
     * @return 结果
     */
    @Operation(summary = "修改密码")
    @PostMapping("/updatePassword")
    public AjaxResult updatePassword(@Valid @RequestBody PassWordDto passWordDto){
        EwcTeacher teacher=teacherService.getById(ThirdSessionHolder.getThirdSession().getId());
        //验证旧密码
        AES aes = new AES("CBC", "PKCS7Padding", Constants.AES_KEY.getBytes(), Constants.AES_IV.getBytes());
        String oldPassword=aes.decryptStr(passWordDto.getOldPassword(), CharsetUtil.CHARSET_UTF_8);
        if (!Objects.equals(teacher.getPassword(),DigestUtil.md5Hex(oldPassword))){
            return AjaxResult.error("密码错误,修改失败");
        }
        String newPassword=aes.decryptStr(passWordDto.getNewPassword(), CharsetUtil.CHARSET_UTF_8);
        teacher.setPassword(DigestUtil.md5Hex(newPassword));
        teacherService.updateById(teacher);
        return AjaxResult.success("更新成功");
    }


    /**
     * 验证验证码
     * @param code code
     * @param uuid 唯一id
     */
    public void checkCaptcha(String code, String uuid) throws CaptchaException
    {
        if (StringUtils.isEmpty(code))
        {
            throw new CaptchaException("验证码不能为空");
        }
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
        String captcha = redisService.getCacheObject(verifyKey);
        if (captcha == null)
        {
            throw new CaptchaException("验证码已失效");
        }
        redisService.deleteObject(verifyKey);
        if (!code.equalsIgnoreCase(captcha))
        {
            throw new CaptchaException("验证码错误");
        }
    }
}
